package com.example.chapter07async;

import androidx.appcompat.app.AppCompatActivity;

import android.app.ProgressDialog;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ProgressBar;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLConnection;

/**
 * 【例7-9】  示例工程Demo_07_AsyncTaskDownloadImage演示了使用AsyncTask实现 从网络上异步下载图片并在ImageView中显示。
 *
 * 1，首先在任务开始之前在UI线程中调用onPreExecute()方法中设置进度条的初始状态；
 * 2，然后在异步线程中执行doInBackground()方法以完成下载任务，并在其中调用publishProgress()方法来通知UI线程更新进度状态；
 * 3，之后在UI线程中调用onProgressUpdate()方法更新进度条；
 * 4，最后下载任务完成，UI线程在onPostExecute()中取得下载好的图像，并更新UI显示该图像。
 *
 * 注意：（1）运行本程序，启动Web服务器，并在服务器根路径放置图片IMG_3290.jpg。
 *      （2）运行这个程序时需要在AndroidManifest.xml文件中声明Internet权限。
 *      （3）为保证用户数据和设备的安全，Google针对Android 9.0以上系统的应用程序，要求默认使用加密连接，
 *          系统会禁止App使用所有未加密的连接。因此运行Android 9.0以上系统的设备无论是接收或者发送流量，
 *          都需要使用下一代传输层安全协议，因此使用HttpUrlConnection进行http请求会出现
 *          “Cleartext HTTP traffic to … not permitted”异常。
 *          如果应用使用的是非加密的明文流量的http网络请求，在AndroidManifest.xml文件的
 *          <application>元素中设置属性“android:usesCleartextTraffic="true"”可以解决此问题。
 */
public class MainActivity extends AppCompatActivity {
    private static final String url = "http://img.sgamer.com/lol_sgamer_com/images/20170428/49be2b2b9918d93673638eb4f4f943e7.jpg";
    private Button btn;
    private ImageView imageView;
    private ProgressDialog progressDialog;
    private ProgressBar progressBar;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btn = findViewById(R.id.button);
        imageView = findViewById(R.id.imageView);
        progressBar = findViewById(R.id.progressBar);
        progressDialog = new ProgressDialog(this);
        progressBar.setVisibility(View.VISIBLE);

        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                new ImageDownloadTask().execute(url);
            }
        });

    }


    private class ImageDownloadTask extends AsyncTask<String, Integer, Bitmap>{
        /**
         * 在UI线程中运行，在异步任务开始之前被执行，以便UI线程完成一些初始化动作，如将进度条清零；
         */
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            progressDialog.setMessage("图片下载中");
            progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
            progressDialog.setMax(100);
            progressDialog.setProgress(0);
            progressDialog.show();

            progressBar.setMax(100);
            progressBar.setProgress(0);
        }

        @Override
        protected void onPostExecute(Bitmap bitmap) {
            Log.d("异步下载图片-AsyncTask thread", " >> onPostExecute()，异步任务完成");
            if (bitmap != null) {
                progressDialog.setProgress(100);
                progressDialog.setMessage("图片下载完成!");
                progressDialog.dismiss();
                imageView.setImageBitmap(bitmap);
            } else {
                progressDialog.setMessage("图片下载失败!");
                //mProgressBar.dismiss();
            }
        }
        /**
         * 在publishProgress方法被调用后，UI thread将调用这个方法从而在界面上展示任务的进展情况，例如通过一个进度条进行展示。
         *
         * @param values
         */
        @Override
        protected void onProgressUpdate(Integer... values) {
            super.onProgressUpdate(values);
            Log.d("异步下载图片-UI thread", " >> onProgressUpdate()，异步任务进行中，更新进度条");
            progressDialog.setProgress(values[0]);
            progressBar.setProgress(values[0]);
        }

        /**
         * //完成对图片的下载和进度数值的更新
         *                             //params是一个可变长的数组 在这里我们只传进来了一个url
         * @param strings
         * @return
         */
        @Override
        protected Bitmap doInBackground(String... strings) {
            Bitmap bitmap = null;
            URLConnection connection;
            InputStream is;    //用于获取数据的输入流
            ByteArrayOutputStream bos;    //可以捕获内存缓冲区的数据，转换成字节数组。
            int len;
            float count = 0, total = 100;    //count为图片已经下载的大小 total为总大小
            try {
                //获取网络连接对象
                connection = (URLConnection) new java.net.URL(strings[0]).openConnection();
                //获取当前内容的总长度
                total = (int) connection.getContentLength();
                //获取输入流
                is = connection.getInputStream();
                bos = new ByteArrayOutputStream();
                byte[] data = new byte[1024];
                Log.d("aaaaa",String.valueOf(total));
                while ((len = is.read(data)) != -1) {
                    count += len;
                    bos.write(data, 0, len);
                    //调用publishProgress()公布进度，onProgressUpdate()方法将被执行
                    publishProgress((int) (count / total * 100));
                    Log.d("异步下载图片-AsyncTask thread", " >> doInBackground()，异步任务进行中，准备更新进度条");

                    /*try {
                        Thread.sleep(1);   //为了显示出进度 人为休眠0.001秒:
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }*/
                }
                bitmap = BitmapFactory.decodeByteArray(bos.toByteArray(), 0, bos.toByteArray().length);
                is.close();
                bos.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return bitmap;
        }
    }
}